package com.kyubi.common.config;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
import java.util.Vector;

import weka.core.Instances;
import weka.core.converters.ConverterUtils.DataSource;

/**
 * This class is a singleton configuration reader.
 * @author anand
 *
 */
public class Configuration {

	private static Configuration me = null;
	private static HashMap<String, String> config = new HashMap<String, String>();
	private static String filePath;
	
	/**
	 * Private constructor
	 * @param filePath	the path to the config file
	 */
	private Configuration(String filePath) {
		this.filePath = filePath;
		readConfig();
	}
	
	/**
	 * Function to return the singleton configuration object
	 * @param filePath	the path to the config file
	 * @return	the singleton Configuration object
	 */
	public static Configuration getSingleton(String filePath) {
		if(me == null) {
			me = new Configuration(filePath);
		}
		
		return me;
	}
	
	/**
	 * Function to return the singleton configuration object
	 * @return	the singleton Configuration object
	 */
	public static Configuration getSingleton() {
		return me;
	}
	
	/**
	 * Function to read the configuration file as keys and values
	 */
	public void readConfig() {
		BufferedReader rdr = null;
        String line;

        try {
            rdr = new BufferedReader(new FileReader(filePath));
        } catch (FileNotFoundException fnf) {
            fnf.printStackTrace();
        }

        try {
            while ((line = rdr.readLine()) != null) {
            	if(!line.equals("") || !line.startsWith("#") || !line.startsWith("/")) {
            		String[] tokens = line.split("[ =]+");
            		
            		if(tokens.length >= 2) {
	            		String key = tokens[0];
	            		String value = tokens[1];
	            		
	            		config.put(key, value);
            		}
            	}
            }
        } catch (IOException io) {
            io.printStackTrace();
        }
	}
	
	/**
	 * Function to get the (String) value for the config key
	 * @param key	the config key
	 * @return	the value
	 */
	public String get(String key) {
		if(config.containsKey(key)) {
			return config.get(key);
		} else {
			return null;
		}
	}
	
	/**
	 * Function to get the (Array) value for the config key
	 * @param key	the config key
	 * @return	the string values (array)
	 */
	public String[] getArray(String key) {
		if(config.containsKey(key)) {
			return config.get(key).split(",");
		} else {
			return null;
		}
	}
	
	/**
	 * Function to read tuples (format [t1:v1])
	 * @param key	the config key
	 * @return	the Vector of tuples
	 */
	public Vector<String[]> getTuples(String key) {
		if(config.containsKey(key)) {
			String[] tuples = config.get(key).split(",");
			Vector<String[]> ret = new Vector<String[]>();
			for(int i=0; i<tuples.length; i++) {
				String temp = tuples[i].replaceAll("[\\[\\]]", "");
				//tuples[i] = tuples[i].replace("\\]", "");
				ret.add(temp.split(":"));
			}
			
			return ret;
		} else {
			return null;
		}
	}
	
	/**
	 * Function to read distinct lines from a file
	 * @param filepath	the path of the file
	 * @return	the set of lines
	 */
	public Set<String> getUniqLinesFromFile(String filepath) {
		Set<String> uniq = new HashSet<String>();
		
		BufferedReader rdr = null;
        String line;

        try {
            rdr = new BufferedReader(new FileReader(filepath));
        } catch (FileNotFoundException fnf) {
            fnf.printStackTrace();
            return null;
        }

        try {
            while ((line = rdr.readLine()) != null) {
            	if(!line.equals("")) {
            		uniq.add(line);
            	}
            }
        } catch (IOException io) {
            io.printStackTrace();
            return null;
        }
        
        return uniq;
	}
	
	/**
	 * @deprecated	DO NOT USE
	 */
	public String getCommaSeparatedLinesFromFile(String filepath) {
		StringBuffer str = new StringBuffer();
		
		BufferedReader rdr = null;
        String line;

        try {
            rdr = new BufferedReader(new FileReader(filepath));
        } catch (FileNotFoundException fnf) {
            fnf.printStackTrace();
            return null;
        }

        try {
            while ((line = rdr.readLine()) != null) {
            	if(!line.equals("")) {
            		str.append("\"" + line + "\",");
            	}
            }
        } catch (IOException io) {
            io.printStackTrace();
            return null;
        }
        
        if(str.length() > 0) {
        	// delete last comma
        	str.deleteCharAt(str.length()-1);
        }
        
        return str.toString();
	}
	
	/**
	 * @deprecated	DO NOT USE
	 */
	public Instances readARFF(String filename) {
		try {
			DataSource source = new DataSource(filename);
			return source.getDataSet();
		} catch(Exception e) {
			e.printStackTrace();
			return null;
		}
	}
}
